
// Otto DIY Web 控制台主应用

class OttoController {
    constructor() {
        this.socket = null;
        this.currentSection = 'dashboard';
        this.robotStatus = {
            battery: 85,
            temperature: 25,
            volume: 60,
            motionMode: '待机',
            wifiConnected: true,
            aiConnected: false
        };
        
        this.init();
    }

    init() {
        this.initSocket();
        this.initNavigation();
        this.initControls();
        this.initForms();
        this.initFileUpload();
        this.startStatusUpdates();
    }

    // Socket.IO 初始化
    initSocket() {
        this.socket = io();
        
        this.socket.on('connect', () => {
            this.showToast('已连接到机器人', 'success');
            this.updateConnectionStatus(true);
        });

        this.socket.on('disconnect', () => {
            this.showToast('与机器人连接断开', 'warning');
            this.updateConnectionStatus(false);
        });

        this.socket.on('robotStatus', (status) => {
            this.updateRobotStatus(status);
        });

        this.socket.on('configUpdated', (config) => {
            this.showToast('配置已更新', 'success');
        });

        this.socket.on('commandExecuted', (command) => {
            this.showToast(`命令已执行: ${command.action}`, 'info');
        });
    }

    // 导航初始化
    initNavigation() {
        const navLinks = document.querySelectorAll('.nav-link');
        navLinks.forEach(link => {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const target = link.getAttribute('href').substring(1);
                this.showSection(target);
                
                // 更新导航状态
                navLinks.forEach(l => l.classList.remove('active'));
                link.classList.add('active');
            });
        });
    }

    // 显示指定部分
    showSection(sectionName) {
        const sections = document.querySelectorAll('.section');
        sections.forEach(section => {
            section.style.display = 'none';
        });
        
        const targetSection = document.getElementById(sectionName);
        if (targetSection) {
            targetSection.style.display = 'block';
            this.currentSection = sectionName;
        }
    }

    // 控制按钮初始化
    initControls() {
        // 方向控制
        const controlButtons = document.querySelectorAll('.btn-control');
        controlButtons.forEach(button => {
            button.addEventListener('click', () => {
                const command = button.getAttribute('data-command');
                this.sendControlCommand(command);
            });
        });

        // 动作按钮
        const actionButtons = document.querySelectorAll('.btn-action');
        actionButtons.forEach(button => {
            button.addEventListener('click', () => {
                const action = button.getAttribute('data-action');
                this.sendActionCommand(action);
            });
        });
    }

    // 表单初始化
    initForms() {
        // Wi-Fi 配置表单
        const wifiForm = document.getElementById('wifi-form');
        if (wifiForm) {
            wifiForm.addEventListener('submit', (e) => {
                e.preventDefault();
                this.saveWifiConfig();
            });
        }

        // 语音配置表单
        const voiceForm = document.getElementById('voice-form');
        if (voiceForm) {
            voiceForm.addEventListener('submit', (e) => {
                e.preventDefault();
                this.saveVoiceConfig();
            });
        }

        // AI 配置表单
        const aiForm = document.getElementById('ai-form');
        if (aiForm) {
            aiForm.addEventListener('submit', (e) => {
                e.preventDefault();
                this.saveAIConfig();
            });
        }

        // 运动配置表单
        const motionForm = document.getElementById('motion-form');
        if (motionForm) {
            motionForm.addEventListener('submit', (e) => {
                e.preventDefault();
                this.saveMotionConfig();
            });
        }
    }

    // 文件上传初始化
    initFileUpload() {
        const uploadForm = document.getElementById('upload-form');
        const fileInput = document.getElementById('dance-file');

        if (uploadForm) {
            uploadForm.addEventListener('submit', (e) => {
                e.preventDefault();
                this.uploadDanceFile();
            });
        }

        if (fileInput) {
            fileInput.addEventListener('change', (e) => {
                const file = e.target.files[0];
                if (file) {
                    this.validateDanceFile(file);
                }
            });
        }
    }

    // 发送控制命令
    sendControlCommand(command) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('controlCommand', { action: command });
            this.updateMotionMode(`执行中: ${command}`);
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 发送动作命令
    sendActionCommand(action) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('controlCommand', { action: action });
            this.updateMotionMode(`动作: ${action}`);
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 更新机器人状态
    updateRobotStatus(status) {
        this.robotStatus = { ...this.robotStatus, ...status };
        
        // 更新UI
        this.updateBattery(status.battery);
        this.updateTemperature(status.temperature);
        this.updateVolume(status.volume);
        this.updateMotionMode(status.motionMode);
        this.updateConnectionStatus(status.wifiConnected, status.aiConnected);
        
        // 更新时间
        document.getElementById('last-update').textContent = new Date().toLocaleTimeString();
    }

    // 更新电量显示
    updateBattery(level) {
        const batteryElement = document.getElementById('battery-level');
        const progressElement = document.getElementById('battery-progress');
        
        if (batteryElement) {
            batteryElement.textContent = `${Math.round(level)}%`;
        }
        
        if (progressElement) {
            progressElement.style.width = `${level}%`;
            
            // 根据电量改变颜色
            if (level > 50) {
                progressElement.className = 'progress-bar bg-success';
            } else if (level > 20) {
                progressElement.className = 'progress-bar bg-warning';
            } else {
                progressElement.className = 'progress-bar bg-danger';
            }
        }
    }

    // 更新温度显示
    updateTemperature(temp) {
        const tempElement = document.getElementById('temperature');
        if (tempElement) {
            tempElement.textContent = `${Math.round(temp)}°C`;
        }
    }

    // 更新音量显示
    updateVolume(level) {
        const volumeElement = document.getElementById('volume-level');
        const progressElement = document.getElementById('volume-progress');
        
        if (volumeElement) {
            volumeElement.textContent = `${Math.round(level)}%`;
        }
        
        if (progressElement) {
            progressElement.style.width = `${level}%`;
        }
    }

    // 更新运动模式
    updateMotionMode(mode) {
        const modeElement = document.getElementById('motion-mode');
        if (modeElement) {
            modeElement.textContent = mode;
        }
    }

    // 更新连接状态
    updateConnectionStatus(wifiConnected, aiConnected) {
        const wifiStatus = document.getElementById('wifi-status');
        const aiStatus = document.getElementById('ai-status');
        
        if (wifiStatus) {
            if (wifiConnected) {
                wifiStatus.textContent = '已连接';
                wifiStatus.className = 'badge bg-success';
            } else {
                wifiStatus.textContent = '未连接';
                wifiStatus.className = 'badge bg-danger';
            }
        }
        
        if (aiStatus) {
            if (aiConnected) {
                aiStatus.textContent = '已连接';
                aiStatus.className = 'badge bg-success';
            } else {
                aiStatus.textContent = '未连接';
                aiStatus.className = 'badge bg-danger';
            }
        }
    }

    // 保存 Wi-Fi 配置
    saveWifiConfig() {
        const ssid = document.getElementById('wifi-ssid')?.value;
        const password = document.getElementById('wifi-password')?.value;
        
        if (!ssid) {
            this.showToast('请输入Wi-Fi名称', 'warning');
            return;
        }
        
        const config = {
            type: 'wifi',
            ssid: ssid,
            password: password
        };
        
        if (this.socket && this.socket.connected) {
            this.socket.emit('updateConfig', config);
            this.showToast('Wi-Fi配置已保存', 'success');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 保存语音配置
    saveVoiceConfig() {
        const keywords = document.getElementById('voice-keywords')?.value;
        const sensitivity = document.getElementById('voice-sensitivity')?.value;
        
        const config = {
            type: 'voice',
            keywords: keywords || 'Otto,小智,机器人',
            sensitivity: sensitivity || 5
        };
        
        if (this.socket && this.socket.connected) {
            this.socket.emit('updateConfig', config);
            this.showToast('语音配置已保存', 'success');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 保存 AI 配置
    saveAIConfig() {
        const endpoint = document.getElementById('ai-endpoint')?.value;
        const apikey = document.getElementById('ai-apikey')?.value;
        
        if (!endpoint) {
            this.showToast('请输入AI服务地址', 'warning');
            return;
        }
        
        const config = {
            type: 'ai',
            endpoint: endpoint,
            apikey: apikey
        };
        
        if (this.socket && this.socket.connected) {
            this.socket.emit('updateConfig', config);
            this.showToast('AI配置已保存', 'success');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 保存运动配置
    saveMotionConfig() {
        const walkSpeed = document.getElementById('walk-speed')?.value;
        const turnSpeed = document.getElementById('turn-speed')?.value;
        
        const config = {
            type: 'motion',
            walkSpeed: walkSpeed || 5,
            turnSpeed: turnSpeed || 5
        };
        
        if (this.socket && this.socket.connected) {
            this.socket.emit('updateConfig', config);
            this.showToast('运动配置已保存', 'success');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 上传舞步文件
    uploadDanceFile() {
        const fileInput = document.getElementById('dance-file');
        const file = fileInput?.files[0];
        
        if (!file) {
            this.showToast('请选择文件', 'warning');
            return;
        }
        
        const formData = new FormData();
        formData.append('danceFile', file);
        
        fetch('/api/upload-dance', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                this.showToast('舞步文件上传成功', 'success');
                this.loadDanceFiles();
                fileInput.value = '';
            } else {
                this.showToast('上传失败: ' + data.error, 'error');
            }
        })
        .catch(error => {
            console.error('上传错误:', error);
            this.showToast('上传失败', 'error');
        });
    }

    // 验证舞步文件
    validateDanceFile(file) {
        if (!file.name.endsWith('.json')) {
            this.showToast('请选择JSON格式的文件', 'warning');
            return false;
        }
        
        if (file.size > 1024 * 1024) { // 1MB
            this.showToast('文件大小不能超过1MB', 'warning');
            return false;
        }
        
        return true;
    }

    // 加载舞步文件列表
    loadDanceFiles() {
        fetch('/api/dances')
            .then(response => response.json())
            .then(files => {
                this.displayDanceFiles(files);
            })
            .catch(error => {
                console.error('加载舞步文件失败:', error);
            });
    }

    // 显示舞步文件列表
    displayDanceFiles(files) {
        const danceList = document.getElementById('dance-list');
        if (!danceList) return;
        
        if (files.length === 0) {
            danceList.innerHTML = `
                <div class="text-center text-muted">
                    <i class="fas fa-music fa-3x mb-3"></i>
                    <p>暂无舞步文件</p>
                    <p>请上传 .json 格式的舞步文件</p>
                </div>
            `;
            return;
        }
        
        danceList.innerHTML = files.map(file => `
            <div class="dance-item">
                <div class="d-flex justify-content-between align-items-center">
                    <div>
                        <div class="dance-name">${file.name}</div>
                        <div class="dance-info">
                            大小: ${this.formatFileSize(file.size)} | 
                            上传时间: ${new Date(file.uploadTime).toLocaleString()}
                        </div>
                    </div>
                    <div class="dance-actions">
                        <button class="btn btn-sm btn-primary" onclick="ottoController.previewDance('${file.name}')">
                            <i class="fas fa-play"></i> 预览
                        </button>
                        <button class="btn btn-sm btn-success" onclick="ottoController.sendDance('${file.name}')">
                            <i class="fas fa-upload"></i> 发送
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="ottoController.deleteDance('${file.name}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');
    }

    // 预览舞步
    previewDance(danceName) {
        fetch(`/api/dance/${danceName}`)
            .then(response => response.json())
            .then(danceData => {
                this.showToast(`预览舞步: ${danceName}`, 'info');
                // 这里可以添加更复杂的预览逻辑
                console.log('舞步数据:', danceData);
            })
            .catch(error => {
                console.error('预览失败:', error);
                this.showToast('预览失败', 'error');
            });
    }

    // 发送舞步到机器人
    sendDance(danceName) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('sendDance', { danceName: danceName });
            this.showToast(`正在发送舞步: ${danceName}`, 'info');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 删除舞步文件
    deleteDance(danceName) {
        if (confirm(`确定要删除舞步文件 "${danceName}" 吗？`)) {
            fetch(`/api/dance/${danceName}`, {
                method: 'DELETE'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    this.showToast('舞步文件已删除', 'success');
                    this.loadDanceFiles();
                } else {
                    this.showToast('删除失败: ' + data.error, 'error');
                }
            })
            .catch(error => {
                console.error('删除错误:', error);
                this.showToast('删除失败', 'error');
            });
        }
    }

    // 格式化文件大小
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    // 开始状态更新
    startStatusUpdates() {
        // 加载舞步文件列表
        this.loadDanceFiles();
        
        // 定期更新状态
        setInterval(() => {
            if (this.socket && this.socket.connected) {
                // 请求最新状态
                this.socket.emit('requestStatus');
            }
        }, 5000); // 每5秒更新一次
    }

    // 显示提示消息
    showToast(message, type = 'info') {
        const toastContainer = document.getElementById('toast-container');
        if (!toastContainer) return;
        
        const toastId = 'toast-' + Date.now();
        const toastHTML = `
            <div id="${toastId}" class="toast align-items-center text-white bg-${type === 'error' ? 'danger' : type === 'success' ? 'success' : type === 'warning' ? 'warning' : 'info'} border-0" role="alert">
                <div class="d-flex">
                    <div class="toast-body">
                        ${message}
                    </div>
                    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
                </div>
            </div>
        `;
        
        toastContainer.insertAdjacentHTML('beforeend', toastHTML);
        
        const toast = new bootstrap.Toast(document.getElementById(toastId));
        toast.show();
        
        // 自动移除
        setTimeout(() => {
            const element = document.getElementById(toastId);
            if (element) {
                element.remove();
            }
        }, 5000);
    }
}

// 初始化应用
let ottoController;
document.addEventListener('DOMContentLoaded', function() {
    ottoController = new OttoController();
});.uploadTime).toLocaleString()}
                        </div>
                    </div>
                    <div class="dance-actions">
                        <button class="btn btn-sm btn-primary" onclick="ottoController.previewDance('${file.name}')">
                            <i class="fas fa-play"></i> 预览
                        </button>
                        <button class="btn btn-sm btn-success" onclick="ottoController.sendDance('${file.name}')">
                            <i class="fas fa-upload"></i> 发送
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="ottoController.deleteDance('${file.name}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');
    }

    // 预览舞步
    previewDance(danceName) {
        fetch(`/api/dance/${danceName}`)
            .then(response => response.json())
            .then(danceData => {
                this.showToast(`预览舞步: ${danceName}`, 'info');
                // 这里可以添加更复杂的预览逻辑
                console.log('舞步数据:', danceData);
            })
            .catch(error => {
                console.error('预览失败:', error);
                this.showToast('预览失败', 'error');
            });
    }

    // 发送舞步到机器人
    sendDance(danceName) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('sendDance', { danceName: danceName });
            this.showToast(`正在发送舞步: ${danceName}`, 'info');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 删除舞步文件
    deleteDance(danceName) {
        if (confirm(`确定要删除舞步文件 "${danceName}" 吗？`)) {
            fetch(`/api/dance/${danceName}`, {
                method: 'DELETE'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    this.showToast('舞步文件已删除', 'success');
                    this.loadDanceFiles();
                } else {
                    this.showToast('删除失败: ' + data.error, 'error');
                }
            })
            .catch(error => {
                console.error('删除错误:', error);
                this.showToast('删除失败', 'error');
            });
        }
    }

    // 格式化文件大小
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    // 开始状态更新
    startStatusUpdates() {
        // 加载舞步文件列表
        this.loadDanceFiles();
        
        // 定期更新状态
        setInterval(() => {
            if (this.socket && this.socket.connected) {
                // 请求最新状态
                this.socket.emit('requestStatus');
            }
        }, 5000); // 每5秒更新一次
    }

    // 显示提示消息
    showToast(message, type = 'info') {
        const toastContainer = document.getElementById('toast-container');
        if (!toastContainer) return;
        
        const toastId = 'toast-' + Date.now();
        const toastHTML = `
            <div id="${toastId}" class="toast align-items-center text-white bg-${type === 'error' ? 'danger' : type === 'success' ? 'success' : type === 'warning' ? 'warning' : 'info'} border-0" role="alert">
                <div class="d-flex">
                    <div class="toast-body">
                        ${message}
                    </div>
                    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
                </div>
            </div>
        `;
        
        toastContainer.insertAdjacentHTML('beforeend', toastHTML);
        
        const toast = new bootstrap.Toast(document.getElementById(toastId));
        toast.show();
        
        // 自动移除
        setTimeout(() => {
            const element = document.getElementById(toastId);
            if (element) {
                element.remove();
            }
        }, 5000);
    }
}.uploadTime).toLocaleString()}
                        </div>
                    </div>
                    <div class="dance-actions">
                        <button class="btn btn-sm btn-primary" onclick="ottoController.previewDance('${file.name}')">
                            <i class="fas fa-play"></i> 预览
                        </button>
                        <button class="btn btn-sm btn-success" onclick="ottoController.sendDance('${file.name}')">
                            <i class="fas fa-upload"></i> 发送
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="ottoController.deleteDance('${file.name}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');
    }

    // 预览舞步
    previewDance(danceName) {
        fetch(`/api/dance/${danceName}`)
            .then(response => response.json())
            .then(danceData => {
                this.showToast(`预览舞步: ${danceName}`, 'info');
                // 这里可以添加更复杂的预览逻辑
                console.log('舞步数据:', danceData);
            })
            .catch(error => {
                console.error('预览失败:', error);
                this.showToast('预览失败', 'error');
            });
    }

    // 发送舞步到机器人
    sendDance(danceName) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('sendDance', { danceName: danceName });
            this.showToast(`正在发送舞步: ${danceName}`, 'info');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 删除舞步文件
    deleteDance(danceName) {
        if (confirm(`确定要删除舞步文件 "${danceName}" 吗？`)) {
            fetch(`/api/dance/${danceName}`, {
                method: 'DELETE'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    this.showToast('舞步文件已删除', 'success');
                    this.loadDanceFiles();
                } else {
                    this.showToast('删除失败: ' + data.error, 'error');
                }
            })
            .catch(error => {
                console.error('删除错误:', error);
                this.showToast('删除失败', 'error');
            });
        }
    }

    // 格式化文件大小
    formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    // 开始状态更新
    startStatusUpdates() {
        // 加载舞步文件列表
        this.loadDanceFiles();
        
        // 定期更新状态
        setInterval(() => {
            if (this.socket && this.socket.connected) {
                // 请求最新状态
                this.socket.emit('requestStatus');
            }
        }, 5000); // 每5秒更新一次
    }

    // 显示提示消息.uploadTime).toLocaleString()}
                        </div>
                    </div>
                    <div class="dance-actions">
                        <button class="btn btn-sm btn-primary" onclick="ottoController.previewDance('${file.name}')">
                            <i class="fas fa-play"></i> 预览
                        </button>
                        <button class="btn btn-sm btn-success" onclick="ottoController.sendDance('${file.name}')">
                            <i class="fas fa-upload"></i> 发送
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="ottoController.deleteDance('${file.name}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');
    }

    // 预览舞步
    previewDance(danceName) {
        fetch(`/api/dance/${danceName}`)
            .then(response => response.json())
            .then(danceData => {
                this.showToast(`预览舞步: ${danceName}`, 'info');
                // 这里可以添加更复杂的预览逻辑
                console.log('舞步数据:', danceData);
            })
            .catch(error => {
                console.error('预览失败:', error);
                this.showToast('预览失败', 'error');
            });
    }

    // 发送舞步到机器人
    sendDance(danceName) {
        if (this.socket && this.socket.connected) {
            this.socket.emit('sendDance', { danceName: danceName });
            this.showToast(`正在发送舞步: ${danceName}`, 'info');
        } else {
            this.showToast('未连接到机器人', 'error');
        }
    }

    // 删除舞步文件
    deleteDance(danceName) {
        if (confirm(`确定要删除舞步文件 "${danceName}" 吗？`)) {
            fetch(`/api/dance/${danceName}`, {
                method: 'DELETE'
            })
            .then(response => response.json())
            .then(data => {.uploadTime).toLocaleString()}
                        </div>
                    </div>
                    <div class="dance-actions">
                        <button class="btn btn-sm btn-primary" onclick="ottoController.previewDance('${file.name}')">
                            <i class="fas fa-play"></i> 预览
                        </button>
                        <button class="btn btn-sm btn-success" onclick="ottoController.sendDance('${file.name}')">
                            <i class="fas fa-upload"></i> 发送
                        </button>
                        <button class="btn btn-sm btn-danger" onclick="ottoController.deleteDance('${file.name}')">
                            <i class="fas fa-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        `).join('');
    }

    // 预览舞步